package com.chushouya.manager.service.common.impl;

import com.chushouya.manager.dao.entity.BonusUserEntity;
import com.chushouya.manager.dao.repository.BonusUserRepository;
import com.chushouya.manager.dto.admin.bonus.BonusQuery;
import com.chushouya.manager.service.common.BonusVerificationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.NoResultException;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 红包核销服务实现
 * 
 * @author chushouya
 * @date 2025-08-13
 */
@Slf4j
@Service
public class BonusVerificationServiceImpl implements BonusVerificationService {
    
    @Resource
    private BonusUserRepository bonusUserRepository;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BigDecimal verifyBonus(Long orderId, Long userId, Long bonusId,BigDecimal bonusPrice, BigDecimal evaluatePrice) {
        log.info("开始核销红包 - 订单ID: {}, 用户ID: {}, 券码: {} {}, 订单金额: {}",
                orderId, userId, bonusId,bonusPrice, evaluatePrice);
        
        try {
            // 1. 查询可用红包
            BonusUserEntity bonus = findAvailableBonus(bonusId, userId);
            if (bonus == null) {
                log.warn("未找到可用红包 - 券码: {}, 用户ID: {}", bonusId, userId);
                return BigDecimal.ZERO;
            }
            
            // 2. 检查红包是否可用
            if (!isBonusAvailable(bonus, evaluatePrice)) {
                log.warn("红包不满足使用条件 - 券码: {}, 订单金额: {}, 最低使用金额: {}",
                        bonusId, evaluatePrice, bonus.getMinAmount());
                return BigDecimal.ZERO;
            }
            
            // 3. 标记红包为已使用
            markBonusAsUsed(bonus.getBonusId(), orderId);
            
            log.info("红包核销成功 - 券码: {}, 核销金额: {}", bonusId, bonus.getTypeMoney());
            return bonus.getTypeMoney();
            
        } catch (Exception e) {
            log.error("红包核销失败 - 券码: {}, 错误: {}", bonusId, e.getMessage(), e);
            throw new RuntimeException("红包核销失败: " + e.getMessage(), e);
        }
    }
    
    @Override
    public BonusUserEntity findAvailableBonus(Long bonusId, Long userId) {
        try {
            BonusQuery query = new BonusQuery();
            query.setBonusId(bonusId);
            query.setUserId(userId);
            return bonusUserRepository.selectOne(query);
            
        } catch (NoResultException e) {
            log.debug("未找到可用红包 - 券码: {}, 用户ID: {}", bonusId, userId);
            return null;
        } catch (Exception e) {
            log.error("查询红包失败 - 券码: {}, 用户ID: {}, 错误: {}", bonusId, userId, e.getMessage(), e);
            return null;
        }
    }
    
    @Override
    public boolean isBonusAvailable(BonusUserEntity bonus, BigDecimal orderAmount) {
        if (bonus == null) {
            return false;
        }
        
        // 检查是否已使用
        if (bonus.getUseTime() != null) {
            log.debug("红包已使用 - 券码: {}, 使用时间: {}", bonus.getTicketNo(), bonus.getUseTime());
            return false;
        }
        
        // 检查时间有效性
        Date now = new Date();
        if (bonus.getStartTime() != null && now.before(bonus.getStartTime())) {
            log.debug("红包未到使用时间 - 券码: {}, 开始时间: {}", bonus.getTicketNo(), bonus.getStartTime());
            return false;
        }
        
        if (bonus.getEndTime() != null && now.after(bonus.getEndTime())) {
            log.debug("红包已过期 - 券码: {}, 结束时间: {}", bonus.getTicketNo(), bonus.getEndTime());
            return false;
        }
        
        // 检查最低使用金额
        if (bonus.getMinAmount() != null && orderAmount.compareTo(bonus.getMinAmount()) < 0) {
            log.debug("订单金额不满足最低使用条件 - 券码: {}, 订单金额: {}, 最低金额: {}", 
                    bonus.getTicketNo(), orderAmount, bonus.getMinAmount());
            return false;
        }
        
        return true;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void markBonusAsUsed(Long bonusId, Long orderId) {
        try {
            BonusUserEntity bonusUserEntity = new BonusUserEntity();
            bonusUserEntity.setBonusId(bonusId);
            bonusUserEntity.setUseTime(new Date());
            bonusUserEntity.setOrderId(orderId);
            bonusUserRepository.updateByPrimaryKeySelective(bonusUserEntity);
            
            log.info("红包标记为已使用 - 红包ID: {}, 订单ID: {}", bonusId, orderId);
            
        } catch (Exception e) {
            log.error("标记红包为已使用失败 - 红包ID: {}, 订单ID: {}, 错误: {}", 
                    bonusId, orderId, e.getMessage(), e);
            throw new RuntimeException("标记红包为已使用失败: " + e.getMessage(), e);
        }
    }
}
